﻿using Miao;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using UnityEngine;


public static class DirectXmlLoader
{
    public static LoadableXmlAsset[] XmlAssetsInModFolder(ModContentPack mod, string folderPath)
    {
        DirectoryInfo directoryInfo;
        //读到def层级
        if (mod.official)
        {
            directoryInfo = new DirectoryInfo(Path.Combine(MiaoFilePaths.OfficialModsFolderPath, mod.Name, folderPath));
        }
        else
        {
            directoryInfo = new DirectoryInfo(Path.Combine(MiaoFilePaths.ModsFolderPath, mod.Name, folderPath));
        }
        if(!directoryInfo.Exists)
        {
            return new LoadableXmlAsset[0];
        }
        //可能需要递归xml全拿，不是很懂原版读取xml的写法
        DirectoryInfo[] SubDefDirectory = directoryInfo.GetDirectories();
        //获取当前目录和所有子目录文件
        FileInfo[] files = directoryInfo.GetFiles("*.xml", SearchOption.AllDirectories);



        LoadableXmlAsset[] assets = new LoadableXmlAsset[files.Length];


        MiaoThreading.ParallelFor(0, assets.Length, delegate (int i)
        {
            FileInfo fileInfo = files[i];
            LoadableXmlAsset loadableXmlAsset = new LoadableXmlAsset(fileInfo.Name, fileInfo.DirectoryName, File.ReadAllText(fileInfo.FullName))
            {
                mod = mod
            };
            assets[i] = loadableXmlAsset;

        });
        return assets;
        //FileInfo[] files = directoryInfo.GetFiles("*.xml", SearchOption.AllDirectories);
    }

    public static T ItemFromXmlFile<T>(string filePath) where T : class, new()
    {
        if (!new FileInfo(filePath).Exists)
        {
            return new T();
        }

        XmlDocument xmlDocument = new XmlDocument();
        StreamReader streamReader = File.OpenText(filePath);
        xmlDocument.Load(streamReader);
        streamReader.Close();

        try
        {
            T result = DirectXmlToObject.ObjectFromXml(xmlDocument.DocumentElement, typeof(T)) as T;
            return result;
        }
        catch (Exception ex)
        {
            Log.Error("Exception loading file at " + filePath + ". Loading defaults instead. Exception was: " + ex.ToString());
            return new T();
        }
    }



    /// <summary>
    /// 我不知道为什么泰南不用跟Def一样的机制读Operation呢，但是我要这么写
    /// </summary>
    /// <param name="node"></param>
    /// <param name="loadingAsset"></param>
    /// <returns></returns>
    public static PatchOperation PatchFromNode(XmlNode node)
    {
        if (node.NodeType != XmlNodeType.Element)
        {
            return null;
        }
        Type typeInAnyAssembly = MiaoTypes.GetTypeInAnyAssembly(node.Name, "Miao");

        if (typeInAnyAssembly == null)
        {
            Debug.LogError($"未找到基于{node.Name}的对应Type");
            return null;
        }
        if (!typeof(PatchOperation).IsAssignableFrom(typeInAnyAssembly))
        {
            return null;
        }

        PatchOperation result = (PatchOperation)DirectXmlToObject.ObjectFromXml(node, typeInAnyAssembly);
        return result;
    }

    public static Def DefFromNode(XmlNode node)
    {
        if (node.NodeType != XmlNodeType.Element)
        {
            return null;
        }
        XmlAttribute xmlAttribute = node.Attributes["Abstract"];//跳过抽象定义
        if (xmlAttribute != null && xmlAttribute.Value.ToLower() == "true")
        {
            return null;
        }
        //用名字反射，机制一样的
        Type typeInAnyAssembly = MiaoTypes.GetTypeInAnyAssembly(node.Name);

        if (typeInAnyAssembly == null)
        {
            return null;
        }
        if (!typeof(Def).IsAssignableFrom(typeInAnyAssembly))
        {
            return null;
        }

        //原流程是反射访问，因为泛型，我全改成基于object的啦
        Def result = (Def)DirectXmlToObject.ObjectFromXml(node, typeInAnyAssembly);
        return result;

    }
}

